namespace DotNetNuke.Services.Log.EventLog.DBLoggingProvider
{
    using DotNetNuke.Common;
    using DotNetNuke.Common.Utilities;
    using DotNetNuke.Services.Log.EventLog;
    using DotNetNuke.Services.Log.EventLog.DBLoggingProvider.Data;
    using DotNetNuke.Services.Mail;
    using DotNetNuke.Services.Scheduling;

    
    using System;
    using System.Collections;
    using System.Data;
    using System.IO;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Threading;
    using System.Web;
    using System.Xml;
    using System.Xml.Serialization;
    using VB2CS;

    public class DBLoggingProvider : LoggingProvider
    {
        private static ReaderWriterLock lockNotif = new ReaderWriterLock();
        private static ReaderWriterLock lockPurgeLog = new ReaderWriterLock();
        public static Collection LogQueue = new Collection();
        private const int ReaderLockTimeout = 0x2710;
        private const int WriterLockTimeout = 0x2710;

        public override void AddLog(LogInfo objLogInfo)
        {
            string ConfigPortalID;
            if (objLogInfo.LogPortalID != Null.NullInteger)
            {
                ConfigPortalID = objLogInfo.LogPortalID.ToString();
            }
            else
            {
                ConfigPortalID = "*";
            }
            LogTypeConfigInfo objLogTypeConfigInfo = this.GetLogTypeConfigInfoByKey(objLogInfo.LogTypeKey, ConfigPortalID);
            if (objLogTypeConfigInfo.LoggingIsActive)
            {
                bool UseEventLogBuffer = true;
                if (DotNetNuke.Common.Globals.HostSettings.ContainsKey("EventLogBuffer"))
                {
                    if (Convert.ToString((DotNetNuke.Common.Globals.HostSettings["EventLogBuffer"])) != "Y")
                    {
                        UseEventLogBuffer = false;
                    }
                }
                else
                {
                    UseEventLogBuffer = false;
                }
                objLogInfo.LogConfigID = objLogTypeConfigInfo.ID;
                LogQueueItem objLogQueueItem = new LogQueueItem();
                objLogQueueItem.LogInfo = objLogInfo;
                objLogQueueItem.LogTypeConfigInfo = objLogTypeConfigInfo;
                SchedulingProvider scheduler = SchedulingProvider.Instance();
                if (((objLogInfo.BypassBuffering | !SchedulingProvider.Enabled) | (scheduler.GetScheduleStatus() == ScheduleStatus.STOPPED)) | !UseEventLogBuffer)
                {
                    this.WriteLog(objLogQueueItem);
                }
                else
                {
                    LogQueue.Add(objLogQueueItem, null, null, null);
                }
            }
        }

        public override void AddLogType(string LogTypeKey, string LogTypeFriendlyName, string LogTypeDescription, string LogTypeCSSClass, string LogTypeOwner)
        {
            DataProvider.Instance().AddLogType(LogTypeKey, LogTypeFriendlyName, LogTypeDescription, LogTypeCSSClass, LogTypeOwner);
        }

        public override void AddLogTypeConfigInfo(string ID, bool LoggingIsActive, string LogTypeKey, string LogTypePortalID, string KeepMostRecent, string LogFileName, bool EmailNotificationIsActive, string Threshold, string ThresholdTime, string ThresholdTimeType, string MailFromAddress, string MailToAddress)
        {
            int intThreshold = -1;
            int intThresholdTime = -1;
            int intThresholdTimeType = -1;
            int intKeepMostRecent = -1;
            if (Versioned.IsNumeric(Threshold))
            {
                intThreshold = Convert.ToInt32(Threshold);
            }
            if (Versioned.IsNumeric(ThresholdTime))
            {
                intThresholdTime = Convert.ToInt32(ThresholdTime);
            }
            if (Versioned.IsNumeric(ThresholdTimeType))
            {
                intThresholdTimeType = Convert.ToInt32(ThresholdTimeType);
            }
            if (Versioned.IsNumeric(KeepMostRecent))
            {
                intKeepMostRecent = Convert.ToInt32(KeepMostRecent);
            }
            DataProvider.Instance().AddLogTypeConfigInfo(LoggingIsActive, LogTypeKey, LogTypePortalID, intKeepMostRecent, EmailNotificationIsActive, intThreshold, intThresholdTime, intThresholdTimeType, MailFromAddress, MailToAddress);
            DataCache.RemoveCache("GetLogTypeConfigInfo");
            DataCache.RemoveCache("GetLogTypeConfigInfoByKey");
        }

        public override void ClearLog()
        {
            DataProvider.Instance().ClearLog();
        }

        public override void DeleteLog(LogInfo LogInfo)
        {
            DataProvider.Instance().DeleteLog(LogInfo.LogGUID);
        }

        public override void DeleteLogType(string LogTypeKey)
        {
            DataProvider.Instance().DeleteLogType(LogTypeKey);
        }

        public override void DeleteLogTypeConfigInfo(string ID)
        {
            DataProvider.Instance().DeleteLogTypeConfigInfo(ID);
            DataCache.RemoveCache("GetLogTypeConfigInfo");
            DataCache.RemoveCache("GetLogTypeConfigInfoByKey");
        }

        private LogProperties Deserialize(string str)
        {
            Stream s = new MemoryStream(Encoding.UTF8.GetBytes(Convert.ToString(str)));
            Type[] l = new Type[] { typeof(LogDetailInfo) };
            XmlSerializer xser = new XmlSerializer(typeof(LogProperties), l);
            return (LogProperties) xser.Deserialize(s);
        }

        private LogInfo FillLogInfo(IDataReader dr)
        {
            LogInfo obj = new LogInfo();
            try
            {
                string LogGUID = Convert.ToString((dr["LogGUID"]));
                obj.LogCreateDate = Convert.ToDateTime((dr["LogCreateDate"]));
                obj.LogGUID = Convert.ToString((dr["LogGUID"]));
                if (!Information.IsDBNull((dr["LogPortalID"])))
                {
                    obj.LogPortalID = Convert.ToInt32((dr["LogPortalID"]));
                }
                if (!Information.IsDBNull((dr["LogPortalName"])))
                {
                    obj.LogPortalName = Convert.ToString((dr["LogPortalName"]));
                }
                if (!Information.IsDBNull((dr["LogServerName"])))
                {
                    obj.LogServerName = Convert.ToString((dr["LogServerName"]));
                }
                if (!Information.IsDBNull((dr["LogUserID"])))
                {
                    obj.LogUserID = Convert.ToInt32((dr["LogUserID"]));
                }
                obj.LogTypeKey = Convert.ToString((dr["LogTypeKey"]));
                obj.LogUserName = Convert.ToString((dr["LogUserName"]));
                obj.LogConfigID = Convert.ToString((dr["LogConfigID"]));
                obj.LogProperties = this.Deserialize(Convert.ToString((dr["LogProperties"])));
            }
            finally
            {
            }
            return obj;
        }

        private Hashtable FillLogTypeConfigInfoByKey(ArrayList arr)
        {
            Hashtable ht = new Hashtable();
            int refIntHelperL0 = arr.Count - 1;
            for (int i = 0; i <= refIntHelperL0; i++)
            {
                LogTypeConfigInfo obj = (LogTypeConfigInfo) arr[i];
                if (obj.LogTypeKey == "")
                {
                    obj.LogTypeKey = "*";
                }
                if (obj.LogTypePortalID == "")
                {
                    obj.LogTypePortalID = "*";
                }
                ht.Add(obj.LogTypeKey + "|" + obj.LogTypePortalID, obj);
            }
            DataCache.SetCache("GetLogTypeConfigInfoByKey", ht);
            return ht;
        }

        public override LogInfoArray GetLog()
        {
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog();
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override LogInfoArray GetLog(int PortalID)
        {
            if (PortalID == -1)
            {
                return this.GetLog();
            }
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog(PortalID);
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override LogInfoArray GetLog(string LogType)
        {
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog(LogType);
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override LogInfoArray GetLog(int PortalID, string LogType)
        {
            if (PortalID == -1)
            {
                return this.GetLog(LogType);
            }
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog(PortalID, LogType);
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override LogInfoArray GetLog(int PageSize, int PageIndex, ref int TotalRecords)
        {
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog(PageSize, PageIndex);
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
                dr.NextResult();
                while (dr.Read())
                {
                    TotalRecords = Convert.ToInt32((dr["TotalRecords"]));
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override LogInfoArray GetLog(int PortalID, int PageSize, int PageIndex, ref int TotalRecords)
        {
            if (PortalID == -1)
            {
                return this.GetLog();
            }
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog(PortalID, PageSize, PageIndex);
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
                dr.NextResult();
                while (dr.Read())
                {
                    TotalRecords = Convert.ToInt32((dr["TotalRecords"]));
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override LogInfoArray GetLog(string LogType, int PageSize, int PageIndex, ref int TotalRecords)
        {
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog(LogType, PageSize, PageIndex);
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
                dr.NextResult();
                while (dr.Read())
                {
                    TotalRecords = Convert.ToInt32((dr["TotalRecords"]));
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override LogInfoArray GetLog(int PortalID, string LogType, int PageSize, int PageIndex, ref int TotalRecords)
        {
            if (PortalID == -1)
            {
                return this.GetLog(LogType);
            }
            LogInfoArray objArr = new LogInfoArray();
            IDataReader dr = DataProvider.Instance().GetLog(PortalID, LogType, PageSize, PageIndex);
            try
            {
                while (dr.Read())
                {
                    LogInfo objLogInfo = this.FillLogInfo(dr);
                    objArr.Add(objLogInfo);
                }
                dr.NextResult();
                while (dr.Read())
                {
                    TotalRecords = Convert.ToInt32((dr["TotalRecords"]));
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            return objArr;
        }

        public override ArrayList GetLogTypeConfigInfo()
        {
            ArrayList arr = (ArrayList) DataCache.GetCache("GetLogTypeConfigInfo");
            if (arr == null)
            {
                IDataReader dr = DataProvider.Instance().GetLogTypeConfigInfo();
                if (dr == null)
                {
                    return new ArrayList();
                }
                arr = CBO.FillCollection(dr, typeof(LogTypeConfigInfo));
                DataCache.SetCache("GetLogTypeConfigInfo", arr);
                this.FillLogTypeConfigInfoByKey(arr);
            }
            return arr;
        }

        public override LogTypeConfigInfo GetLogTypeConfigInfoByID(string ID)
        {
            return (LogTypeConfigInfo) CBO.FillObject(DataProvider.Instance().GetLogTypeConfigInfoByID(Convert.ToInt32(ID)), typeof(LogTypeConfigInfo));
        }

        private LogTypeConfigInfo GetLogTypeConfigInfoByKey(string LogTypeKey, string LogTypePortalID)
        {
            Hashtable ht = (Hashtable) DataCache.GetCache("GetLogTypeConfigInfoByKey");
            if (ht == null)
            {
                ht = this.FillLogTypeConfigInfoByKey(this.GetLogTypeConfigInfo());
            }
            LogTypeConfigInfo objLogTypeConfigInfo = (LogTypeConfigInfo) ht[LogTypeKey + "|" + LogTypePortalID];
            if (objLogTypeConfigInfo == null)
            {
                objLogTypeConfigInfo = (LogTypeConfigInfo) ht["*|" + LogTypePortalID];
                if (objLogTypeConfigInfo != null)
                {
                    return objLogTypeConfigInfo;
                }
                objLogTypeConfigInfo = (LogTypeConfigInfo) ht[LogTypeKey + "|*"];
                if (objLogTypeConfigInfo == null)
                {
                    return (LogTypeConfigInfo) ht["*|*"];
                }
            }
            return objLogTypeConfigInfo;
        }

        public override ArrayList GetLogTypeInfo()
        {
            return CBO.FillCollection(DataProvider.Instance().GetLogTypeInfo(), typeof(LogTypeInfo));
        }

        public override object GetSingleLog(LogInfo LogInfo, LoggingProvider.ReturnType objReturnType)
        {
            IDataReader dr = DataProvider.Instance().GetSingleLog(LogInfo.LogGUID);
            LogInfo obj = null;
            try
            {
                if (dr != null)
                {
                    dr.Read();
                    obj = this.FillLogInfo(dr);
                }
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }
            if (objReturnType == LoggingProvider.ReturnType.LogInfoObjects)
            {
                return obj;
            }
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(XmlUtils.Serialize(obj));
            return xmlDoc.DocumentElement;
        }

        public override bool LoggingIsEnabled(string LogType, int PortalID)
        {
            string ConfigPortalID = PortalID.ToString();
            if (PortalID == -1)
            {
                ConfigPortalID = "*";
            }
            LogTypeConfigInfo obj = this.GetLogTypeConfigInfoByKey(LogType, ConfigPortalID);
            if (obj == null)
            {
                return false;
            }
            return obj.LoggingIsActive;
        }

        public override void PurgeLogBuffer()
        {
            try
            {
                lockPurgeLog.AcquireWriterLock(0x2710);
                Collection c = LogQueue;
                int j = c.Count;
                int refIntHelperL0 = c.Count;
                for (int i = 1; i <= refIntHelperL0; i++)
                {
                    if (c[j] != null)
                    {
                        LogQueueItem objLogQueueItem = (LogQueueItem) c[j];
                        this.WriteLog(objLogQueueItem);
                    }
                    if (c[j] != null)
                    {
                        c.Remove(j);
                    }
                    j--;
                }
                DataProvider.Instance().PurgeLog();
            }
            finally
            {
                lockPurgeLog.ReleaseWriterLock();
            }
        }

        public override void SendLogNotifications()
        {
            ArrayList arrLogConfig = CBO.FillCollection(DataProvider.Instance().GetEventLogPendingNotifConfig(), typeof(LogTypeConfigInfo));
            int refIntHelperL0 = arrLogConfig.Count - 1;
            for (int i = 0; i <= refIntHelperL0; i++)
            {
                LogTypeConfigInfo objLogConfig = (LogTypeConfigInfo) arrLogConfig[i];
                IDataReader dr = DataProvider.Instance().GetEventLogPendingNotif(Convert.ToInt32(objLogConfig.ID));
                string strLog = "";
                try
                {
                    while (dr.Read())
                    {
                        LogInfo objLogInfo = this.FillLogInfo(dr);
                        strLog = strLog + this.Serialize(objLogInfo) + "\r\n\r\n";
                    }
                }
                finally
                {
                    if (dr != null)
                    {
                        dr.Close();
                    }
                }
                dr = null;
                DotNetNuke.Services.Mail.Mail.SendMail(objLogConfig.MailFromAddress, objLogConfig.MailToAddress, "", "Event Notification", strLog, "", "", "", "", "", "");
                DataProvider.Instance().UpdateEventLogPendingNotif(Convert.ToInt32(objLogConfig.ID));
            }
        }

        private string Serialize(object obj)
        {
            Type[] l = new Type[] { typeof(LogDetailInfo) };
            XmlDocument xmlDoc = new XmlDocument();
            XmlSerializer xser = new XmlSerializer(obj.GetType(), l);
            StringWriter sw = new StringWriter();
            xser.Serialize((TextWriter) sw, (obj));
            xmlDoc.LoadXml(sw.GetStringBuilder().ToString());
            return xmlDoc.DocumentElement.OuterXml;
        }

        public override bool SupportsEmailNotification()
        {
            return true;
        }

        public override bool SupportsInternalViewer()
        {
            return true;
        }

        public override bool SupportsSendToCoreTeam()
        {
            return false;
        }

        public override bool SupportsSendViaEmail()
        {
            return true;
        }

        public override void UpdateLogType(string LogTypeKey, string LogTypeFriendlyName, string LogTypeDescription, string LogTypeCSSClass, string LogTypeOwner)
        {
            DataProvider.Instance().UpdateLogType(LogTypeKey, LogTypeFriendlyName, LogTypeDescription, LogTypeCSSClass, LogTypeOwner);
        }

        public override void UpdateLogTypeConfigInfo(string ID, bool LoggingIsActive, string LogTypeKey, string LogTypePortalID, string KeepMostRecent, string LogFileName, bool EmailNotificationIsActive, string Threshold, string ThresholdTime, string ThresholdTimeType, string MailFromAddress, string MailToAddress)
        {
            int intThreshold = -1;
            int intThresholdTime = -1;
            int intThresholdTimeType = -1;
            int intKeepMostRecent = -1;
            if (Versioned.IsNumeric(Threshold))
            {
                intThreshold = Convert.ToInt32(Threshold);
            }
            if (Versioned.IsNumeric(ThresholdTime))
            {
                intThresholdTime = Convert.ToInt32(ThresholdTime);
            }
            if (Versioned.IsNumeric(ThresholdTimeType))
            {
                intThresholdTimeType = Convert.ToInt32(ThresholdTimeType);
            }
            if (Versioned.IsNumeric(KeepMostRecent))
            {
                intKeepMostRecent = Convert.ToInt32(KeepMostRecent);
            }
            DataProvider.Instance().UpdateLogTypeConfigInfo(ID, LoggingIsActive, LogTypeKey, LogTypePortalID, intKeepMostRecent, LogFileName, EmailNotificationIsActive, intThreshold, intThresholdTime, intThresholdTimeType, MailFromAddress, MailToAddress);
            DataCache.RemoveCache("GetLogTypeConfigInfo");
            DataCache.RemoveCache("GetLogTypeConfigInfoByKey");
        }

        private void WriteLog(LogQueueItem objLogQueueItem)
        {
            LogTypeConfigInfo objLogTypeConfigInfo = null;
            try
            {
                objLogTypeConfigInfo = objLogQueueItem.LogTypeConfigInfo;
                if (objLogTypeConfigInfo != null)
                {
                    LogInfo objLogInfo = objLogQueueItem.LogInfo;
                    string LogProperties = this.Serialize(objLogInfo.LogProperties);
                    DataProvider.Instance().AddLog(objLogInfo.LogGUID, objLogInfo.LogTypeKey, objLogInfo.LogUserID, objLogInfo.LogUserName, objLogInfo.LogPortalID, objLogInfo.LogPortalName, objLogInfo.LogCreateDate, objLogInfo.LogServerName, LogProperties, Convert.ToInt32(objLogInfo.LogConfigID));
                    if (objLogTypeConfigInfo.EmailNotificationIsActive)
                    {
                        try
                        {
                            lockNotif.AcquireWriterLock(0x2710);
                            if (objLogTypeConfigInfo.NotificationThreshold == 0)
                            {
                                string str = XmlUtils.Serialize(objLogQueueItem.LogInfo);
                                DotNetNuke.Services.Mail.Mail.SendMail(objLogTypeConfigInfo.MailFromAddress, objLogTypeConfigInfo.MailToAddress, "", "Event Notification", str, "", "", "", "", "", "");
                            }
                            else if (objLogTypeConfigInfo.LogTypeKey != "LOG_NOTIFICATION_FAILURE")
                            {
                            }
                        }
                        finally
                        {
                            lockNotif.ReleaseWriterLock();
                        }
                    }
                }
                if ((objLogTypeConfigInfo.EmailNotificationIsActive && (objLogTypeConfigInfo.NotificationThreshold != 0)) && (objLogTypeConfigInfo.LogTypeKey != "LOG_NOTIFICATION_FAILURE"))
                {
                }
            }
            catch (Exception exception1)
            {

                Exception exc = exception1;
                if (HttpContext.Current != null)
                {
                    HttpResponse response = HttpContext.Current.Response;
                    HtmlUtils.WriteHeader(response, "Unhandled Error");
                    string strMessage = exc.Message;
                    HtmlUtils.WriteError(response, objLogTypeConfigInfo.LogFileNameWithPath, strMessage);
                    HtmlUtils.WriteFooter(response);
                    response.End();
                }

            }
        }
    }
}

